package v1

import (
	"auth/bll"
	"auth/constants"
	"auth/lib/authentication"
	"auth/model"
	"auth/utils"
	"fmt"
	"github.com/gin-gonic/gin"
)

var User = &user{}

func init() {
	RegisterRouter(User)
}

type user struct{}

// Init
func (a *user) Init(r *gin.RouterGroup) {
	g := r.Group("/user")
	{
		g.POST("/register", a.create)
		g.POST("/update", a.update)
		g.POST("/list", a.list)
		g.POST("/delete", a.delete)
		g.POST("/detail", a.find)
		g.POST("/login", a.login)
		g.POST("/refreshToken", a.refreshToken)
	}
}

// refreshToken 刷新token
func (a *user) refreshToken(c *gin.Context) {
	var (
		in  = &model.UserRefreshTokenReq{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	token, err := authentication.Refresh(in.Token)
	if err != nil {
		c.Error(err)
		return
	}

	utils.ResponseOk(c, model.UserRefreshTokenResp{Token: token.Token})
	return

}
func (a *user) login(c *gin.Context) {
	var (
		in  = &model.UserLoginReq{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	find, err := bll.User.Find(c.Request.Context(), &model.UserInfoRequest{
		UserName: in.UserName,
		Email:    in.Email,
		Phone:    in.Phone,
	})
	if err != nil {
		c.Error(err)
		return
	}

	// 密码校验
	if find.Password != utils.EncryptionSha256(in.Password, find.Salt) {
		c.Error(fmt.Errorf("password is wrong"))
		return
	}

	// 生成token
	token, err := authentication.Generate(&authentication.Options{
		UserID: fmt.Sprintf("%v", find.Id),
		Roles:  []int64{1},
	}, constants.ExpireTime)
	if err != nil {
		c.Error(fmt.Errorf("生成token失败！"))
		return
	}

	if _, err := authentication.Extract(token.Token); err != nil {
		c.Error(err)
		return
	} else {
		utils.ResponseOk(c, &model.UserLoginResp{
			Token: token.Token,
		})
	}
}

// create
func (a *user) create(c *gin.Context) {
	var (
		in  = &model.UserCreateRequest{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	// 参数校验
	if in.Password == "" || (in.Username == "" && in.Email == "" && in.Phone == "") {
		c.Error(fmt.Errorf("用户名或密码不能为空！"))
		return
	}

	// 密码加密
	in.Salt = utils.RandString(16)
	in.Password = utils.EncryptionSha256(in.Password, in.Salt)
	if err = bll.User.Create(c.Request.Context(), in); err != nil {
		c.Error(err)
		return
	}
	utils.ResponseOk(c, nil)
}

// update
func (a *user) update(c *gin.Context) {
	var (
		in  = &model.UserUpdateRequest{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	if err = bll.User.Update(c.Request.Context(), in); err != nil {
		c.Error(err)
		return
	}
	utils.ResponseOk(c, nil)
}

// list
func (a *user) list(c *gin.Context) {
	var (
		in  = &model.UserListRequest{}
		out = &model.UserListResponse{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	if out, err = bll.User.List(c.Request.Context(), in); err != nil {
		c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// list
func (a *user) find(c *gin.Context) {
	var (
		in  = &model.UserInfoRequest{}
		out = &model.UserInfo{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	if out, err = bll.User.Find(c.Request.Context(), in); err != nil {
		c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// delete
func (a *user) delete(c *gin.Context) {
	var (
		in  = &model.UserDeleteRequest{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	if err = bll.User.Delete(c.Request.Context(), in); err != nil {
		c.Error(err)
		return
	}
	utils.ResponseOk(c, nil)
}
